<?

	if (!defined("PATH_CONVERT"))	
		define("PATH_CONVERT","/usr/local/bin/convert");

	if (!defined("PATH_COMPOSITE"))	
		define("PATH_COMPOSITE","/usr/local/bin/composite");
		
	
	// section for an image include. 

	function &processImageData(&$pictureIn, $options) {	
	
		//for fault finding??
		$debug = extractBooleanWithKeyFromArray('debug', $options, false);

		//this is to remove the evil exif etc.. that makes big ugly pictures.
		$stripProfile = extractBooleanWithKeyFromArray('stripProfile', $options, true);

		//resizing options
		$width = extractNumberWithKeyFromArray('width', $options, null);
		$height = extractNumberWithKeyFromArray('height', $options, null);
		$preserveAspectRatio = extractBooleanWithKeyFromArray('preserveAspectRatio', $options, true);
		$filter = extractStringWithKeyFromArray('filter',$options, null);
		
		//this allows images that are smaller than the specified size to be scaled up anyway..
		$upscaleSmallerImages = extractBooleanWithKeyFromArray('upscaleSmallerImages',$options,false);
		$onlyResizeIfSmaller = extractBooleanWithKeyFromArray('onlyResizeIfSmaller', $options, false);
		
		$crop = extractBooleanWithKeyFromArray('crop', $options, false);
		
		//if we want to water mark...
		$waterMark = extractNumberWithKeyFromArray('waterMark',$options,null);
		
		//output quality options.
		$quality = extractNumberWithKeyFromArray('quality', $options, 80);
		
		//options for additional commands .. 
		$additionalCommands=extractStringWithKeyFromArray('additionalCommands',$options,null);
		
		
		$command = "";
		//$debug = false;
		if ($debug) {
			$command .= " -verbose ";
		}
		
		//do we want to remove the profile from jpeg information.. yeah.. i think we do..
		if ($stripProfile) {
			$command .= " +profile '*'";
		}
	
		if(is_string($filter) && strlen($filter) > 0 ){
			$command .= " -filter ". $filter;
		}
			
		if (!is_null($width) || !is_null($height)) {

			//resize filter 

		
			$resize ="";
			if(!is_null($width) && $width > 0 ){
				$resize .= $width;
			}
			if(!is_null($height) && $height > 0){
				$resize .= "x" . $height;
			}

			//scale if bigger 
			if (!$upscaleSmallerImages){
				$resize .="'>'";
			}
			
			//scale if smaller
			if ($onlyResizeIfSmaller){
				$resize .="'<'";
			}
						
			//force the scaled size
			if (!$preserveAspectRatio){
				$resize .="!";
			}
			$command .= " -resize " .$resize;
		}
				
// the caption command will be straight imagemagic options plus a csv list of values to insert.. based on the order
// of the appearance of a place holder	
		if (!is_null($additionalCommands) && strlen($additionalCommands) > 0 ){
			$command .= " " .$additionalCommands;
			
		}

		
		
		//we need to look at moving this.. elsewhere.. it may be able to be dropped into the additonal commands..
		$compositeCommand = null;
		if (!is_null($waterMark) && strlen($waterMark) > 3){
			
			//$waterMarkPosition = extractString
			$waterMarkParts = explode(":",$waterMark);
			if (count($waterMarkParts) == 2){
				//next we need to get the options.. etc..
				$compositeCommand = " | " . PATH_COMPOSITE . ($debug ? " -verbose " : "") . " -compose src-over -gravity " . $waterMarkParts[1] . " " .  $waterMarkParts[0] . " - - ";
			}
		}
		
		
		//default command line.. with the quality..
		$command .=  " -quality " . $quality;		
		$command = PATH_CONVERT . " - " . $command . " JPEG:- " . $compositeCommand ;
		syslog( LOG_INFO , CMS_HTTP_HOST . " imagemagic executing: " . $command . " see log for details");
//		echo $command;
//		die;
//		header("x-canI_has_A-image-k0mand-lein: " . $command);
		
		
		$descriptorspec = array(
		   0 => array("pipe", "r"),  // stdin is a pipe that the child will read from
		   1 => array("pipe", "w"),  // stdout is a pipe that the child will write to
		   2 => array("file", CMS_BINARY_CACHE_PATH ."/error-output.txt", "a") // stderr is a file to write to
		);
		
		$process = proc_open($command, $descriptorspec, $pipes);
		if (is_resource($process)) {
		 
			fwrite($pipes[0], $pictureIn);
			fclose($pipes[0]);
		   
			$out="";
			//read the output
			while (!feof($pipes[1])) {
				$out .= fgets($pipes[1], 1024);
			}
			fclose($pipes[1]);
			$returnValue = proc_close($process);
		
		}
		
		if ($returnValue === 0)
			return $out;
		else
			return 0;
	}
		
	//Backup function for determining mime types
	if (!function_exists ("mime_content_type")) {
		 function mime_content_type($file) {
			 return exec ("file -bi " . escapeshellcmd($file));
		 }
	}
	
	//fucntion to translate the size of a file directly into kb
	function convert_size($size) {
	   for($si = 0; $size >= 1024; $size /= 1024, $si++);
	   return round($size, 0)."".substr(' kMGT', $si, 1)."B";
	}

	function getBinaryRecordForDocumentCodeAndId($documentCode, $binaryId , $db){
		$q = "SELECT id, documentcode, elementid, filetypecode, filename, mimetype, filesize, filename FROM binarydata WHERE documentcode=".$documentCode." AND id=" .$binaryId . " LIMIT 1";
	    $db->executeQuery($q);	
	    if ($db->numRows() == 1) {
	    	return $db->nextAssoc();
	    }
	    return null;
	}

	function getBinaryRecordForDocumentCodeAndElementId($documentCode, $elementId ,$fileTypeCode, $db){
		$q = "SELECT id, documentcode, elementid, filetypecode, filename, mimetype, filesize, filename FROM binarydata WHERE documentcode=".$documentCode." AND filetypecode=" . $fileTypeCode . " AND elementid=" .$elementId . " LIMIT 1";
	    $db->executeQuery($q);	
	    if ($db->numRows() == 1) {
	    	return $db->nextAssoc();
	    }
	    return null;
	}

	// this will be moved into the content tabe once we split out core cms content and normal user content
	// into two different tables.
	function getImageDescriptor($documentTypeCode, $elementId, $fileTypeCode,  $db) {
		$q = "SELECT width, height, quality, filter, preserveaspectratio AS preserveAspectRatio, upscalesmallerimages AS upscaleSmallerImages, onlyresizeifsmaller AS onlyResizeIfSmaller, watermark AS waterMark, additionalcommands AS additionalCommands  FROM imagedescriptor WHERE documenttypecode='" . $documentTypeCode . "' AND filetype='" . $fileTypeCode . "'";
		if (!is_null($elementId) && $elementId > 0){
			$q .=" AND elementid=" . $elementId ;
		}
		$q .=" LIMIT 1";// we only want one item.
		
		$db->executeQuery($q);
//	   $db->executeQuery($q);	
	  if ($db->numRows() == 1) {
	    	return $db->nextAssoc();
	   }
	    return null;
	}
	
	/**
	 * @desc This function preprocesses the additional imagemagick commands for an image, it looks up the additional commands
	 * and performs the argument replacement and returns the additonal commands as a string.
	 *
	 * @param stdclass $document
	 * @param integer $elementId
	 * @param integer $fileTypeCode
	 * @param CmsDatabaseConnection $db
	 * 
	 * @return string
	 */
	function preProcessAdditionalCommandsForDocumentElementAndFileType($document, $elementId, $fileTypeCode, &$db){
		$additionalCommands ="";
		
		$imageDescriptor = getImageDescriptor($document->documenttypecode, $elementId, $fileTypeCode,$db);
		
		if (!$imageDescriptor)
			return null;
		
		if ( array_key_exists('additionalCommands',$imageDescriptor) && 0 < strlen($imageDescriptor['additionalCommands']))	{
			/*
				The additional commands string will have two parts separated by a colon, the first part is the command with place holders
				which are question marks, and the second, a comma separated list of values.. to substitute in.. if the option is contained
				in {{ }} it will be considered to be the name of a field on the main document..
				eg:
				-command ? +command ?x? :a0,a1,....,an
			*/
			//$args = explode("&",$imageDescriptor['additionalCommands']);
			$additionalCommands = $imageDescriptor['additionalCommands'];
					
						$additionalCommands = trim($additionalCommands);
						if (0 < strlen($additionalCommands)){
							
							$GLOBALS['preProcess']['documentcode'] = $document;
							$ret =preg_replace_callback(
        						'/({{.*}})/',
        create_function(
            '$matches',
            'preg_match("/{{(.*)}}/",$matches[0],$m);
            $document = $GLOBALS[\'preProcess\'][\'documentcode\'];
			$s = preg_replace("/\r\n|\n\r/","\\\\n",$document->{$m[1]});
			return $s;'
        )
        						,
						        $additionalCommands
    						);
    						unset($GLOBALS['preProcess']['documentcode']);
							return $ret;
        						
						}
		}
		return "";
	}

?>